﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using ComLib;
using ComLib.Data;
using ComLib.Entities;
using ComLib.Queue;

using ComLib.WebModules.Tags;
using ComLib.WebModules.Helpers;


namespace ComLib.WebModules.Services
{
    /// <summary>
    /// DTO object for handling tags on any entity.
    /// </summary>
    public class TagsEntry
    {
        public string Tags;
        public int GroupId;
        public int RefId;
    }



    /// <summary>
    /// Tag queue processor.
    /// </summary>
    public class TagQueue : QueueProcessor<TagsEntry>
    {

        private static TagQueue _instance = new TagQueue();
        private static Timer _timer;

        /// <summary>
        /// Start the TagQueue processing.
        /// </summary>
        /// <param name="intervalInSeconds"></param>
        public static void Start(int intervalInSeconds)
        {
            _timer = new Timer(DoProcess, string.Empty, 5000, intervalInSeconds * 1000);            
        }


        /// <summary>
        /// Stop the tag processing.
        /// </summary>
        public static void Stop()
        {
            _timer.Dispose();
        }


        /// <summary>
        /// Process the tags.
        /// </summary>
        public static void DoProcess(object ctx)
        {
            _instance.Process();
        }


        /// <summary>
        /// Enqueue the entry.
        /// </summary>
        /// <param name="entry"></param>
        public static void DoEnqueue(TagsEntry entry)
        {
            _instance.Enqueue(entry);
        }


        /// <summary>
        /// Process the entries.
        /// </summary>
        /// <param name="itemsToProcess"></param>
        protected override void Process(IList<TagsEntry> itemsToProcess)
        {            
            if(itemsToProcess == null || itemsToProcess.Count == 0)
                return;
            
            foreach (var entry in itemsToProcess)
            {
                string error = string.Format("Unable to apply tags for GroupId[{0}], RefId[{1}], Tags[{2}]", entry.GroupId, entry.RefId, entry.Tags);
                ExecuteHelper.TryCatchLog( error, () =>
                {
                    // Delete existing tags for the associated group/ref id combination.
                    Tag.GetRepository().Delete(Criteria.New().Where<Tag>(t => t.GroupId).Is(entry.GroupId)
                                                             .And<Tag>(t => t.RefId).Is(entry.RefId));

                    // Convert string to Tag objects.
                    List<Tag> tags = TagHelper.ConvertToTags(entry.Tags, entry.GroupId, entry.RefId);
                    if (tags != null && tags.Count > 0)
                    {
                        foreach (var tag in tags) Tag.Create(tag);
                    }
                });
            }            
        }
    }
}
